#ifndef GAMEWORLD_H
#define GAMEWORLD_H

#include <string>
#include <vector>
#include <QtGui>

#include "shipobject.h"
#include "watertile.h"
#include "highscores.h"

using namespace std;

class GameWorld
{
    QList<ShipObject> opponentships;
    QList<ShipObject> playerships;
    int numPlayerShips;
    int numOpponentShips;
    vector<WaterTile*> watertiles;
    vector<WaterTile*> opponentwatertiles;
    vector<HighScores*> scores;
    int rows, cols;
    QString curDifficulty;

    QString username;

    //for cheat mode
    bool cheatMode;

    //Score for least number of moves
    unsigned int score;

    static GameWorld gameworld;

    GameWorld(int initRows, int initCols, int numShips) : rows(initRows), cols(initCols), numPlayerShips(numShips),
        numOpponentShips(numShips) {}
public:

    ShipObject createShip(const string& type, const int& row, const int& col, const string &img, const bool &portrait);
    WaterTile *createTile(const string& type, const int& row, const int& col, const string& img);
    WaterTile *createOpponentTile(const string& type, const int& row, const int& col, const string& img);

    //adds ships to gameworld
    void addShip(ShipObject obj) {
        opponentships.push_back(obj);
    }

    //adds watertiles to gameworld
    void addTile(WaterTile *obj) {
        watertiles.push_back(obj);
    }
    void addOpponentTile(WaterTile *obj) { opponentwatertiles.push_back(obj); }
    void addHighScore(HighScores *obj){
        scores.push_back(obj);
    }
    bool Fire(WaterTile *tile, QString whichPlayer);

    //returns first object found at position <row>, <col>, or NULL if none
    ShipObject *getByPosition(int row, int col);

    //returns object with <id>, or NULL if none
    ShipObject getById(int id);

    ShipObject *getByShipType(QString shipType, QString whichPlayer);


    //SAVE & LOAD
    void save();
    void load();

    void setNumShips(QString whichplayer, int newnum);

    //grid dimension and count of ships in the game
    enum {
        EASYDIM = 8,
        NORMALDIM = 10,
        HARDDIM = 20,
        SHIPS = 10,
        SHIPS2 = 4,
        SHIPS3 = 3,
        SHIPS4 = 2,
        SHIPS5 = 1
    };

    //set difficulty
    void setDifficulty(QString newDifficulty) { curDifficulty = newDifficulty; }

    //get difficulty
    QString getDifficulty() { return curDifficulty; }
    //get Score
    int getScore() { return score;}
    //set Score
    void setScore(int initScore) { score = initScore;}


    //Get Vectors
    QList<ShipObject>& getOpponentShips() { return opponentships; }
    vector<WaterTile*>& getWaterTiles() { return watertiles; }
    vector<WaterTile*>& getOpponentWaterTiles() { return opponentwatertiles; }

    int getNumShips(QString whichPlayer);

    vector<HighScores*>& getHighScores() { return scores;}

    QList<ShipObject>& getPlayerShips() { return playerships; }
    void addPlayerShip(ShipObject newShip) { playerships.push_back(newShip); }
    void clearPlayerShips() { playerships.clear(); }


    void decShips(QString whichPlayer);

    void clearShipSelections();

    //set cheat mode
    void setCheatMode(const bool& newbool) { cheatMode = newbool; }

    //get cheat mode status
    bool getCheatMode() { return cheatMode; }

    void setUserName(QString newname) { username = newname; }
    QString getUserName() { return username; }

    void saveGame();
    void loadGame();

    //Destroy watertiles
    ~GameWorld();

    //Get singleton
    static GameWorld& instance() { return gameworld; }

    void resetWorld();
};

extern GameWorld gameworld;

#endif // GAMEWORLD_H
